﻿using System.Text;
using SoftwareConsulting.BI11.NumericalMethods.Interfaces;

namespace SoftwareConsulting.BI11.NumericalMethods.Optimization
{
    /// <summary>
    /// Класс вектора, подозрительного на оптимальный, в методах оптимизации многоаргументных функций
    /// </summary>
    public abstract class SuspiciousOptimalVector
    {
	    private double _value; //значение в векторе	    
        private double[] _argument; //положение вектора	    
        private IManyVariableFunction _function;//оптимизируемая функция

        /// <summary>
        /// Возвращает/устанавливает оптимизируемую функцию
        /// </summary>
        protected IManyVariableFunction Function
        {
            get
            {
                return _function;
            }
            set
            {
                _function = value;
            }
        }

        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="argument"></param>
        /// <param name="function"></param>
        public SuspiciousOptimalVector(double[] argument, IManyVariableFunction function)
        {
            _argument = argument;
            _function = function;
            _value = _function.GetValue(_argument);
        }

        /// <summary>
        /// Возвращает флаг вектора, более подходящего на оптимальный, чем указанный
        /// </summary>
        /// <param name="otherVector"></param>
        /// <returns></returns>
        public abstract bool BetterThan(SuspiciousOptimalVector otherVector);
        
        /// <summary>
        /// Стягивает от указанной точки
        /// </summary>
        /// <param name="fromPoint"></param>
        public void ContractFrom(double[] fromPoint)
        {
            for (int i = 0; i < _argument.Length; i++)
            {
                _argument[i] += fromPoint[i];
                _argument[i] *= 0.5;
            }
            _value = _function.GetValue(_argument);
        }

        /// <summary>
        /// Возвращает положение вектора
        /// </summary>
        public double[] Argument
        {
            get 
            {
                return _argument; 
            }
        }

        /// <summary>
        /// Возвращает значение в векторе
        /// </summary>
        public double Value
        {
            get 
            { 
                return _value; 
            }
        }
        
        protected abstract string PrintedKey();

        /// <summary>
        /// Возвращает как строку
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(_value);
            sb.Append(PrintedKey());
            for (int i = 0; i < _argument.Length; i++)
            {
                sb.Append(' ');
                sb.Append(_argument[i]);
            }
            return sb.ToString();
        }
    }
}
